<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    // mysql注册
        // Navicat for MySQL 15中文版
            // mysql安装后先不要打开
            // 注册机放入软件安装目录下
            // 以管理员身份运行注册机
            // 选择Navicat v15 product选择mysql, language选择simplified chinese (注意不要选错版本)
            // 再点击patch按纽 弹出navicat.exe-x64 ->Cracked继续
            // Generate获取激活码
            // 这时打开软件，点击注册按纽
            // 再点击激活按纽，点击手动激活
            // 将requese值复制到注册机生成激活码
        
/*
    命令
        首先【开始】> 输入mysql > 打开命令行
    sql
        删除
            delete from user where id = ?
        修改
            update userset balance = balance - ? where username = ?

    语法【分号不能丢】
        显示所有数据库
            show databases;
        新建数据库
            create database 库名;
        删除数据库
            drop database 库名;
        选择数据库
            use 库名;
        查看当前选择的库
            select databases;
        查看当前库下的所有表
            show tables;
        创建表
            create table 表名(
                id int primary key auto_increment,
                username varchar(16),
                password varchar(16)
            );
        删除表
            drop table 表名
        查看表结构 (查看表里面有的所有字段)
            desc 表名;
        插入数据 (数据位置对应表头位置, 不需要插入的可以补null)
            insert into 表名 values(null, '星河络', '');
        插入数据 (只对某些列进行插入)
            insert into 表名(username, password) values('123', '333')
        查看数据
            select * from 表名;
        删除数据
            delete from 表名; -删除所有
            delete from 表名 id = 6; -删除id列是6的
        修改数据
            update 表名 set username = '小凤凰' where id = 7; -修改username列，修改条件是id列是7
        修改表名
            rename table 表名 to 新表名

    JDBC编程
        public static void main(String[] args) {
            Class.forName('com.mysql.jdbc.Driver'); //注册驱动
            // 连接数据库 (连接web01库 设置编码 设置时区)
            String url = "jdbc:mysql//localhost:3306/web01?useUnicode=true&characterEncoding=UTF8&serverTimezone=UTC";
            String user = "root";
            String password = "123456";
            Connect con = DriverManager.getConnection(url, user, password);

            // 发起请求 并接收结果
            Statement stmt = con.createStatement();
            ResultSet rs = stmt.executeQuery("select * from user");// executeXXX

            // 循环结果 .next()如果有下一条将继续循环
            white(rs.next()){
                rs.getInt(1); //获取第1列 int型
                rs.getString(2); //获取第2列 String型
                rs.getInt(3); //获取第3列 int型

                //可以传递列名
                rs.getInt("id");
                rs.getString("username");
                rs.getInt("password");
            }
            //关闭连接（倒序关闭）
            if(rs!=null)rs.close();
            if(stmt!=null)stmt.close();
            if(con!=null)con.close();
        }
    连接出现错误
        错误信息 有SSL字段
        解决 url后加上 useSSL=false
        错误信息 有serverTimezone字段
        解决 url后加上 serverTimezone=UTC
    sql注入
        假设
            现已有selectByUsernamePassword方法需要传入username和password
            方法中执行的sql语句是 "select * from user where username = '"+username+"' and password = '"+password+"'"
        selectByUsernamePassword("admin", "123456")//正常判断
        selectByUsernamePassword("admin", "123456' or '1' = '1")//sql注入
            解释
                密码后面的第一个单引号是提前结束字符串
                后面追加条件 or '1' = '1   (或者是'1'= '1 这里最后没有单引号是因为sql语句中的最后一个单引号补上)
                形成最后的sql语句 select * from user where username = 'admin' and password = '123456' or '1'='1'
    sql注入问题
        使用PreparedStatement可以防止sql注入
    查询
        Connection con = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;

        String sql = "select * from user where username = ? password = ?";
        stmt = con.prepareStatement(sql);
        stmt.setString(1, 'admin');
        stmt.setString(2, '123456');
        rs = stmt.executeQuery();
    插入
        String sql = "insert into user(username, password) values(?,?)"
        stmt = con.prepareStatement(sql);
        stmt.setString(1, username);
        stmt.setString(2, password);
        int result = stmt.executeUpdate();// 返回值代表收到影响的行数
    事务
        如果因为不可避免的原因造成程序中断 进行事务回滚
        开启事务
            con.setAutoCommit(false);
        提交事务
            con.commit();
        例
            con.setAutoCommit(false);//开启事务
            String sql = "update user set balance = balance - ? where username = ?";
            stmt1 = con.prepareStatement(sql);
            stmt1.setInt(1, money);
            stmt1.setString(2, username1);
            stmt1.executeUpdate();

            String n = null;
            n.charAt(2);//空指针异常

            sql = "update user set balance = balance + ? where username = ?";
            stmt2 = con.prepareStatement(sql);
            stmt2.setInt(1, money);
            stmt2.setString(2, username2);
            stmt2.executeUpdate();

            con.commit();//提交事务
    DBCP（导入可能需要pool包, log包）
        BasicDataSource ds = new BasicDataSource();
        ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
        ds.serUrl(ConnectionURL);
        ds.setUsername(username);
        ds.setPassword(password);

        ds.setInitialSize(5);//初始连接个数
        ds.setMaxTotal(20);//最多连接个数
        ds.setMinIdle(3);//最小空闲连接个数

    c3p0
        

*/
</script>
</html>